﻿/**
* @description  Singleton class for loading and managing text strings for entire application.
*/
package com.foed.managers {

	import flash.events.IOErrorEvent;
	import flash.events.SecurityErrorEvent;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.net.URLLoader;
	import flash.net.URLRequest;
	import flash.system.Capabilities;
	
	public class LabelManager extends EventDispatcher {
	
		static private var sLabelManager:LabelManager;
		static private var ENGLISH_LABELS:String = "english.xml";
		static private var SPANISH_LABELS:String = "spanish.xml";
		static private var FRENCH_LABELS:String = "french.xml";
		static private var GERMAN_LABELS:String = "german.xml";

		static public var language:String;
		static public var ENGLISH:String = "en";
		static public var SPANISH:String = "es";
		static public var FRENCH:String = "fr";
		static public var GERMAN:String = "de";

		private var _labels:Object;
		private var _ready:Boolean;

		/**
		* @description  Constructor for Singleton class.
		*/
		public function LabelManager() {
			_labels = {};
			_ready = false;
			getLabels();
		}

		/**
		* @description  Returns only instance of Singleton class.
		*
		* returns  The single LabelManager instance.
		*/
		static public function getInstance():LabelManager {
			if (sLabelManager == null) sLabelManager = new LabelManager();
			return sLabelManager;
		}

		/**
		* @description  Loads in the proper language XML file to populate labels.
		*/
		private function getLabels():void {
			switch (LabelManager.language || Capabilities.language) {
				case SPANISH:
					loadFile(SPANISH_LABELS);
					break;
				case FRENCH:
					loadFile(FRENCH_LABELS);
					break;
				case GERMAN:
					loadFile(GERMAN_LABELS);
					break;
				default:
					loadFile(ENGLISH_LABELS);
			}
		}

		/**
		* @description  Loads the specified XML file.
		*
		* @param  pFile  The file to load. 
		*/
		private function loadFile(pFile:String):void {
			var pLoader:URLLoader = new URLLoader();
			pLoader.addEventListener(Event.COMPLETE, onLoadComplete);
			pLoader.addEventListener(IOErrorEvent.IO_ERROR, onLoadError);
			pLoader.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onLoadError);
			try {
				pLoader.load(new URLRequest(pFile));
			} catch (e:Error) {
				onError(e.message);
			}
		}

		/**
		* @description  Event handler for the successful load of XML.
		*
		* @param  pEvent  Event fired by URLLoader.
		*/
		private function onLoadComplete(pEvent:Event):void {
			var pContent:XML = new XML(URLLoader(pEvent.target).data);
			var pLabels:XMLList = pContent.child("label");
			for each (var pLabel:XML in pLabels) {
				_labels[pLabel.@key] = pLabel.valueOf();
			}
			informListeners();
		}

		/**
		* @description  Event handler for an error loading XML.
		*
		* @param  pEvent  Event fired by URLLoader.
		*/
		private function onLoadError(pEvent:ErrorEvent):void {
			onError(pEvent.type + ": " + pEvent.text);
		}

		/**
		* @description  Traces the loading error and informs listeners of completeness.
		*
		* @param  pError  The String error message.
		*/
		private function onError(pError:String):void {
			trace(pError);
			informListeners();
		}

		/**
		* @description  Sets the _ready flag and dispatches complete event to all listeners.
		*/
		private function informListeners():void {
			_ready = true;
			dispatchEvent(new Event(Event.COMPLETE));
		}

		/**
		* @description  Returns whether the LabelManager has loaded its labels.
		*
		* @returns  True if labels have been loaded and are ready to be accessed.
		*/
		public function get ready():Boolean {
			return _ready;
		}

		/**
		* @description  Returns a text string stored by the specified key.
		*
		* @param  pKey  The key for how a particular text string has been stored.
		*
		* @returns  The text string stored by the specified key.
		*/
		public function getLabel(pKey:String):String {
			return _labels[pKey] || pKey;
		}

	}
		
}